home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dirut / dosdir21.zip / FILELIST.C < prev    next >
C/C++ Source or Header  |  1994-06-22  |  11KB  |  471 lines

  1. /*
  2.    FILELIST.C
  3.  
  4.    Example program uses dosdir directory functions (dd_findfirst,
  5.    dd_findnext, dd_fnsplit, and dd_match) on MS-DOS, Unix, and VMS
  6.    platforms demonstrating application portability.
  7.  
  8.    This program lists files matching the filemask and
  9.    recursively acts on subdirectories (if selected).
  10.  
  11.    Copyright (C) 1994 Jason Mathews.
  12.    Permission is granted to any individual or institution to use, copy,
  13.    or redistribute this software so long as it is not sold for profit,
  14.    provided this copyright notice is retained.
  15.  
  16.    Modification history:
  17.     V1.0  17-May-94  Original version.
  18.     V1.1   8-Jun-94  Handle VMS stuff.
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <time.h>
  25. #include "dosdir.h"
  26. #include "match.h"
  27.  
  28. #ifdef VMS
  29. #  define EXIT_OK 1
  30. #  define ALT_SW || *argv[i]=='/'
  31. #  define CHDIR(s) vms_chdir(s)
  32. #else
  33. #  define EXIT_OK 0
  34. #  define CHDIR(s) chdir(s)
  35. #  ifdef MSDOS
  36. #    define ALT_SW || *argv[i]=='/'
  37. #  else /* ?UNIX */
  38. #    define ALT_SW
  39. #  endif /* ?MSDOS */
  40. #endif /* ?VMS */
  41.  
  42. typedef struct TDirTag {
  43.     char* dirname;
  44.     struct TDirTag *next;
  45. } TDirEntry;
  46.  
  47. typedef struct {
  48.     TDirEntry *head, *tail;
  49. } TDirList;
  50.  
  51. /* Global variables */
  52.  
  53. char filemask[DD_MAXFILE+DD_MAXEXT];
  54. int  attrib = DD_NORMAL;
  55. long total_bytes = 0, dir_bytes;
  56. unsigned total_files = 0, dir_files;
  57. unsigned num_directories = 0;
  58. const char *default_mask = ALL_FILES_MASK;
  59. int (*filematch) OF(( const char*, const char*, int ));
  60.  
  61. /* Function prototypes */
  62.  
  63. void findfiles  OF((char* dir));
  64. int  strcompare OF((const char*, const char*, int));
  65. void q_insert   OF((TDirList *list, const char *s));
  66. int  q_remove   OF((TDirList *list, char *s));
  67. void PrintSummary OF((char* title, int flags, char* drive, char* path));
  68.  
  69. #if defined (VMS)
  70.  
  71. int vms_chdir(char* dir)
  72. {
  73.   /* kill version number on directories */
  74.   char* s = strchr(dir, ';');
  75.   if (s) *s = '\0';
  76.   return chdir(dir);
  77. }
  78.  
  79. /*---------------------------------------------------------------------*
  80. Name            strupr - converts a string to upper-case
  81.  
  82. Description     strupr converts lower-case letters in string str to upper-case.
  83.         No other changes occur.
  84. *---------------------------------------------------------------------*/
  85. char* strupr(const char* s)
  86. {
  87.       register char *ps = s;
  88.       while (*ps)
  89.     {
  90.         if (islower((unsigned char)*ps))
  91.         *ps = _toupper((unsigned char)*ps);
  92.         ps++;
  93.     }
  94.   return s;
  95. }
  96.  
  97. #elif defined (MSDOS)
  98.  
  99. /* No valid MS-DOS directories start with a period (.),
  100.  * except for .. or ., so anything with a period prefix
  101.  * must be special.
  102.  */
  103. #  define SpecialDir(f) (*(f) == '.')
  104.  
  105. #else  /* ? UNIX */
  106.  
  107. int SpecialDir OF((const char *path));
  108.  
  109. /* Function: SpecialDir
  110.  *
  111.  * Purpose:  Test for special directories
  112.  *
  113.  * Returns: 1 if path = "." or ".."
  114.  *          0 otherwise.
  115.  */
  116. int SpecialDir(path)
  117.      const char *path;
  118. {
  119.   if (*path != '.') return 0;
  120.   if (*(++path) == '.') path++;
  121.   return (*path=='/' || *path=='\0');
  122. }
  123.  
  124. #endif /* ?VMS */
  125.  
  126. int strcompare(s1, s2, ignore_case)
  127.     const char *s1, *s2;
  128.     int ignore_case;
  129. {
  130.     return !strcmp(s1, s2);
  131. }
  132.  
  133. void findfiles(dir)
  134.     char* dir;
  135. {
  136.   static dd_ffblk fb;       /* file block structure */
  137.   static char tmp[DD_MAXDIR];      /* tmp string buffer */
  138.   int rc;                       /* error code */
  139.   TDirList list;                /* directory queue */
  140.  
  141.   if (dir)
  142.     {
  143. #ifdef MSDOS
  144.       int len = strlen(dir);
  145.       /* strip ending separator (if present), which DOS doesn't like. */
  146.       if (len > 1 && dir[len-1]==DIR_END) dir[len-1] = 0;
  147. #endif /* ?MSDOS */
  148.       if (CHDIR(dir)) return; /* ?err */
  149.     }
  150.  
  151.   rc = dd_findfirst( default_mask, &fb, attrib | DD_DIREC );
  152.   list.head = list.tail = 0;
  153.   dir_files = 0;
  154.   dir_bytes = 0;
  155.  
  156.   while (rc==0)
  157.     {
  158.       if (attrib & DD_DIREC && DD_ISDIREC(fb.dd_mode))
  159.     {
  160. #ifndef VMS
  161.       /*  Ignore directory entries starting with '.'
  162.        *  which includes the current and parent directories.
  163.        */
  164.      if (!SpecialDir(fb.dd_name))
  165. #endif /* ?!VMS */
  166.         q_insert(&list, fb.dd_name);
  167.     }
  168.  
  169.       /* if match then do something with the file */
  170.       if (filematch(fb.dd_name, filemask, 0))
  171.     {
  172.       char period;
  173.       struct tm* t = localtime(&fb.dd_time);
  174.  
  175.       if (!dir_files++)
  176.         {
  177.         int len;
  178.         getcwd(tmp, sizeof(tmp));
  179. #ifndef VMS
  180.         len = strlen(tmp);
  181.         if (len==0 || tmp[--len] == DIR_END)
  182.         tmp[len] = '\0';
  183. #endif /* ?!VMS */
  184.         ++num_directories; /* increment dir count */
  185.         printf("\nDirectory of %s", tmp);
  186. #ifdef VMS
  187.         printf("%s\n\n", filemask);
  188. #else
  189.         printf("%c%s\n\n", DIR_END, filemask);
  190. #endif /* ?VMS */
  191.         }
  192.  
  193.       if (DD_ISDIREC(fb.dd_mode))
  194.         printf(" <DIR>  ");
  195.       else
  196.         {
  197.         dir_bytes += fb.dd_size;
  198.         printf("%8ld", fb.dd_size);
  199.         }
  200.  
  201.       if (t->tm_hour < 12)
  202.       {
  203.           /* zero hour in local time might be negative */
  204.           if (t->tm_hour < 0) t->tm_hour = 0;
  205.           period = 'a';
  206.       }
  207.       else
  208.         {
  209.           period = 'p';
  210.           if (t->tm_hour != 12) t->tm_hour -= 12;
  211.         }
  212.  
  213.       /* Print Date & Time */
  214.  
  215.       printf(" %2d-%02d-%2d  %2d:%02d%cm %s\n",
  216.          t->tm_mon+1, t->tm_mday,
  217.          t->tm_year, t->tm_hour,
  218.          t->tm_min, period, fb.dd_name);
  219.     }
  220.  
  221.       rc = dd_findnext(&fb);
  222.     } /* while !rc */
  223.  
  224.   if (dir_files)
  225.     {
  226.       printf("\t%8ld bytes in %u file(s)\n", dir_bytes, dir_files);
  227.       total_files += dir_files;
  228.       total_bytes += dir_bytes;
  229.     }
  230.  
  231.   /* recursively parse subdirectories (if any) */
  232.   while (q_remove(&list, tmp))
  233.     findfiles(tmp);
  234.  
  235.   if (dir) chdir(DIR_PARENT); /* go to parent directory */
  236. }
  237.  
  238. /*
  239.  * q_insert - insert directory name to queue
  240.  */
  241. void q_insert(list, s)
  242.      TDirList *list;
  243.      const char *s;
  244. {
  245.   TDirEntry *ptr;
  246.   int len = strlen(s);
  247.   if (!len) return;
  248.   if ((ptr = (TDirEntry*) malloc(sizeof(TDirEntry))) == NULL )
  249.   {
  250.     perror("malloc");
  251.     return;
  252.   }
  253.   if ((ptr->dirname = (char*) malloc(len+1)) == NULL )
  254.   {
  255.       perror("malloc");
  256.       free(ptr);
  257.       return;
  258.   }
  259.   strcpy(ptr->dirname, s);
  260.   ptr->next = NULL;
  261.   if (!list->head) list->head = ptr;
  262.   else list->tail->next = ptr;
  263.   list->tail = ptr;
  264. }
  265.  
  266. /*
  267.  *  q_remove - remove directory name from queue
  268.  */
  269. int q_remove(list, s)
  270.      TDirList *list;
  271.      char *s;
  272. {
  273.   TDirEntry *ptr = list->head;
  274.   if (!ptr) return 0;        /* queue empty? */
  275.   strcpy(s, ptr->dirname);
  276.   list->head = ptr->next;
  277.   free(ptr->dirname);
  278.   free(ptr);
  279.   return 1;            /* okay */
  280. }
  281.  
  282. /*
  283.  *  Print summary of file totals
  284.  */
  285. void PrintSummary(title, flags, drive, path)
  286.     int flags;
  287.     char *title, *drive, *path;
  288. {
  289.     printf("%s", title);
  290.     if (flags & DRIVE) printf("%s", drive);
  291.     if (flags & DIRECTORY)
  292.     {
  293. #ifndef VMS
  294.     int len = strlen(path);
  295.     if (len==0 || path[--len] == DIR_END)
  296.       path[len] = '\0';
  297. #endif /* ?!VMS */
  298.     printf("%s", path);
  299.     }
  300. #ifdef VMS
  301.     printf("%s\n", filemask);
  302. #else
  303.     printf("%c%s\n", DIR_END, filemask);
  304. #endif /* ?VMS */
  305.  
  306.     if (total_files)
  307.     printf("\t%8ld bytes in %u file(s)\n", total_bytes, total_files);
  308.     else
  309.     printf("\nno files found\n");
  310. }
  311.  
  312. int main(argc, argv)
  313.      int argc;
  314.      char** argv;
  315. {
  316.   int  i, disk = -1;
  317.   int  flags = 0;
  318.   char *path = 0;
  319.   char homedir[DD_MAXDIR];   /* current working directory */
  320.   char drive[DD_MAXDRIVE];
  321.   char dir[DD_MAXDIR];
  322.   char file[DD_MAXFILE];
  323.   char ext[DD_MAXEXT];
  324.  
  325.   for (i=1; i < argc; i++)
  326.     {
  327.       if (*argv[i]=='-' ALT_SW)
  328.     switch (argv[i][1]) {
  329.     case 'S':
  330.     case 's':
  331.       attrib |= DD_DIREC;
  332.       break;
  333. #ifdef MSDOS
  334.     case 'H':
  335.     case 'h':
  336.       attrib |= DD_HIDDEN | DD_SYSTEM;
  337.       break;
  338. #endif /* ?MSDOS */
  339.     default:
  340.       printf("FILELIST - DOSDIR Application by Jason Mathews\n\n");
  341. #ifdef MSDOS
  342.       printf("Usage:  filelist [path][file] [-h] [-s]\n");
  343. #else /* ?UNIX/VMS */
  344.       printf("Usage:  filelist [path][file] [-s]\n");
  345. #endif /* ?MSDOS */
  346.       printf("  path  = Directory path to start searching.\n");
  347.       printf("  file  = File(s) to search (Default=%s).\n", default_mask);
  348. #ifdef M